package com.css.fxfzxczh.modules.lossAssessment.houseCategoryArea.service;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.css.fxfzxczh.base.annotation.EntityValue;
import com.css.fxfzxczh.base.annotation.Transform;
import com.css.fxfzxczh.base.attachment.entity.AttachmentInfoEntity;
import com.css.fxfzxczh.base.attachment.repository.AttachmentInfoRepository;
import com.css.fxfzxczh.base.dict.repository.DictItemRepository;
import com.css.fxfzxczh.base.dict.repository.entity.DictItemEntity;
import com.css.fxfzxczh.base.remote.RemoteService;
import com.css.fxfzxczh.base.response.RestResponse;
import com.css.fxfzxczh.common.utils.ObjUtils;
import com.css.fxfzxczh.constants.FxfzConstants;
import com.css.fxfzxczh.modules.boundary.entity.BoundaryEntity;
import com.css.fxfzxczh.modules.boundary.repository.BoundaryRepository;
import com.css.fxfzxczh.modules.buildingKilometerGrid.repository.FxqhBuildingGridRepository;
import com.css.fxfzxczh.modules.fieldWorkManage.surTaskManage.entity.SurTaskManage;
import com.css.fxfzxczh.modules.fieldWorkManage.surTaskManage.repository.SurTaskManageRepository;
import com.css.fxfzxczh.modules.lossAssessment.houseCategoryArea.entity.HouseCategoryArea;
import com.css.fxfzxczh.modules.lossAssessment.houseCategoryArea.param.QueryParam;
import com.css.fxfzxczh.modules.lossAssessment.houseCategoryArea.repository.HouseCategoryAreaRepository;
import com.css.fxfzxczh.modules.lossAssessment.houseCategoryArea.vo.BuildGridFindAllVo;
import com.css.fxfzxczh.modules.lossAssessment.houseCategoryArea.vo.DistrictVO;
import com.css.fxfzxczh.modules.lossAssessment.houseCategoryArea.vo.StructureVO;
import com.css.fxfzxczh.modules.lossReportManage.lossReportEscalation.repository.GovOffInfoRepository;
import com.css.fxfzxczh.modules.lossReportManage.lossReportEscalation.repository.OtherHouseInfoRepository;
import com.css.fxfzxczh.modules.lossReportManage.lossReportEscalation.repository.ResHouInfoRepository;
import com.css.fxfzxczh.modules.map.entity.FieldDesc;
import com.css.fxfzxczh.modules.map.entity.SeismicInfluence;
import com.css.fxfzxczh.modules.synthesizeInfoManage.earEveManage.entity.EarEveManage;
import com.css.fxfzxczh.modules.synthesizeInfoManage.earEveManage.repository.EarEveManageRepository;
import com.css.fxfzxczh.modules.synthesizeInfoManage.earEveManage.service.EarEveManageService;
import com.css.fxfzxczh.util.*;
import com.css.fxfzxczh.zcpt.sys.entity.SUser;
import com.css.fxfzxczh.zcpt.sys.service.SysAreaService;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.HashBiMap;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.internal.LinkedTreeMap;
import lombok.val;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.*;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Dbj
 * @date 2023年05月31日  17:53
 */
@Service
public class HouseCategoryAreaService {
    @Resource
    HouseCategoryAreaRepository houseCategoryAreaRepository;
    @Resource
    SurTaskManageRepository surTaskManageRepository;
    @Resource
    BoundaryRepository boundaryRepository;
    @Resource
    @Qualifier("myExecutor")
    private Executor executor;
    @Resource
    DictItemRepository dictItemRepository;
    @Resource
    EarEveManageRepository earEveManageRepository;
    @Resource
    private AttachmentInfoRepository attachmentInfoRepository;
    @Resource
    private SysAreaService sysAreaService;
    @Resource
    private RedisTemplate<String, String> redisTemplate;
    @Value("${basicData.url}")
    private String divisionUrl;
    @Resource
    RemoteService remoteService;

    @Resource
    EarEveManageService earEveManageService;

    @Resource
    ResHouInfoRepository resHouInfoRepository;

    @Resource
    GovOffInfoRepository govOffInfoRepository;

    @Resource
    OtherHouseInfoRepository otherHouseInfoRepository;


    @Autowired
    private FxqhBuildingGridRepository fxqhBuildingGridRepository;


    /**
     * 大区划新增普查数据时调用接口同步到现场调查系统中
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteAndSavePcData(Map<String,Object> map) {
        String type = (String)map.get("type");
        int count = houseCategoryAreaRepository.deletePcData(type);
        if(count>0){
            List<BuildGridFindAllVo> vos = (List<BuildGridFindAllVo>) map.get("vos");
            houseCategoryAreaRepository.batchSavePcData(vos);
        }
    }

    public List<HouseCategoryArea> getHouseCategoryArea(QueryParam queryParam) {
        //获取之前生成保存的数据
        List<HouseCategoryArea> areaList = houseCategoryAreaRepository.getHouseCategoryArea(queryParam);
        if (PlatformObjectUtils.isNotEmpty(areaList)) {
            return areaList;
        }
        return new ArrayList<>(0);
    }
    @Transactional(rollbackFor = Exception.class)
    public List<HouseCategoryArea> mathHouseCategoryArea(String dataFrom,String attachId,String ratio,String versionCode) throws Exception{
        //先删除该地震事件下已存在的数据(真删)
        EarEveManage currentEvent = earEveManageService.getCurrentEvent();
        String xsemId = currentEvent.getXsemId();
        String xsemCode = currentEvent.getEventCode();
        houseCategoryAreaRepository.deleteByEarthQuake(currentEvent.getXsemId());
        List<HouseCategoryArea> areaList = new ArrayList<>();
        //教育系统在医疗教育中所占比例
        String finalRatio = removePercent(ratio);
        //1 报表；2：普查；3：文件
        if ("1".equals(dataFrom)){
            List<HouseCategoryArea> list=new ArrayList<>();
            //获取 居住房屋基础资料报表数据
            List<HouseCategoryArea> resHouInfoList=resHouInfoRepository.getDataByXsemId(xsemId);
            //获取 政府办公用房基础资料报表数据
            List<HouseCategoryArea> govOffInfoList=govOffInfoRepository.getDataByXsemId(xsemId);
            //获取 其他房屋基础资料报表数据
            List<HouseCategoryArea> otherHouseInfoList=otherHouseInfoRepository.getDataByXsemId(xsemId);
            if(CollectionUtils.isNotEmpty(resHouInfoList)){
                list.addAll(resHouInfoList);
            }
            if(CollectionUtils.isNotEmpty(govOffInfoList)){
                list.addAll(govOffInfoList);
            }
            if(CollectionUtils.isNotEmpty(otherHouseInfoList)){
                list.addAll(otherHouseInfoList);
            }
            if(CollectionUtils.isEmpty(list)){
                throw new RuntimeException("报表数据为空，请在【地震灾害损失报表上报】模块上传报表数据");
            }
            //开始构建子区数据
            List<HouseCategoryArea> surTaskData = getSurTaskData(list, xsemCode, finalRatio,currentEvent.getXsemId(),versionCode);
            areaList.addAll(surTaskData);

        }else if ("2".equals(dataFrom)) {
            //获取地震事件关联的评估子区
            List<SurTaskManage> allData = surTaskManageRepository.getAllDefineDataByCode(currentEvent.getXsemId());
            if (PlatformObjectUtils.isEmpty(allData) || allData.size() == 0) {
                throw new RuntimeException("该地震事件没有查询到任何的评估子区");
            }
            //每个评估子区
            for (SurTaskManage surTaskManage : allData) {
                //根据评估子区空间数据获取到子区涉及到的区县并返回重合部分的空间数据
                List<String> boundaryList = boundaryRepository.getCountyBoundaryList(surTaskManage.getGeom());
                //根据涉及到的区县从13张表中获取对应区县的数据
                if (PlatformObjectUtils.isNotEmpty(boundaryList)) {
                    for(String geom:boundaryList){
                        //List<BuildGridFindAllVo> voList1 = houseCategoryAreaRepository.getPcData(geom);

                        List<BuildGridFindAllVo> voList = getBuildGridData(versionCode,geom,Collections.emptyList());

                        //factVos是这个区县在评估子区中的所有的数据
                        if (PlatformObjectUtils.isNotEmpty(voList)) {
                            //处理数据为指定格式 list是一个子区下的每一个区县的下指定格式的数据
                            List<HouseCategoryArea> list = handleData(voList, surTaskManage, finalRatio,currentEvent.getXsemId());
                            //areaList保存每个子区每个区县下的数据
                            areaList.addAll(list);
                        }
                    }
                }
            }
        } else if ("3".equals(dataFrom)) {
            try {
                //开始解析excel数据
                List<HouseCategoryArea> list = analysisExcel(attachId);
                if (PlatformObjectUtils.isNotEmpty(list)) {
                    //开始构建子区数据
                    List<HouseCategoryArea> surTaskData = getSurTaskData(list, xsemCode, finalRatio,currentEvent.getXsemId(),versionCode);
                    areaList.addAll(surTaskData);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if(areaList.size()>0){
            houseCategoryAreaRepository.batchSave(areaList);
        }
        return areaList;
    }


    public static Map<String, Object> getPropertiesAsMap(Object obj) {
        Map<String, Object> map = new HashMap<>();
        Field[] fields = obj.getClass().getDeclaredFields();

        for (Field field : fields) {
            field.setAccessible(true); // 如果字段是私有的，需要设置为可访问
            try {
                Object value = field.get(obj); // 获取字段的值
                map.put(field.getName(), value); // 将字段名作为键，值作为值存入Map
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return map;
    }

    private List<BuildGridFindAllVo>  getBuildGridData(String versionCode,String geom,List<String> codeList) {
        Map<String, List<BuildGridFindAllVo>> map = new HashMap<>();
        map.put("rural_bottom_frame", fxqhBuildingGridRepository.findByVersionCodeAndGeom("fxqh_building_grid_rural_bottom_frame",versionCode,geom,codeList, BuildGridFindAllVo.class));
        map.put("rural_civil", fxqhBuildingGridRepository.findByVersionCodeAndGeom("fxqh_building_grid_rural_civil",versionCode,geom,codeList, BuildGridFindAllVo.class));
        map.put("rural_masonry", fxqhBuildingGridRepository.findByVersionCodeAndGeom("fxqh_building_grid_rural_masonry",versionCode,geom,codeList, BuildGridFindAllVo.class));
        map.put("rural_mixed", fxqhBuildingGridRepository.findByVersionCodeAndGeom("fxqh_building_grid_rural_mixed",versionCode,geom,codeList, BuildGridFindAllVo.class));
        map.put("rural_other", fxqhBuildingGridRepository.findByVersionCodeAndGeom("fxqh_building_grid_rural_other",versionCode,geom,codeList, BuildGridFindAllVo.class));
        map.put("rural_steel", fxqhBuildingGridRepository.findByVersionCodeAndGeom("fxqh_building_grid_rural_steel",versionCode,geom,codeList, BuildGridFindAllVo.class));
        map.put("rural_steel_concrete", fxqhBuildingGridRepository.findByVersionCodeAndGeom("fxqh_building_grid_rural_steel_concrete",versionCode,geom,codeList, BuildGridFindAllVo.class));
        map.put("rural_wood_bamboo", fxqhBuildingGridRepository.findByVersionCodeAndGeom("fxqh_building_grid_rural_wood_bamboo",versionCode,geom,codeList, BuildGridFindAllVo.class));
        map.put("urban_masonry", fxqhBuildingGridRepository.findByVersionCodeAndGeom("fxqh_building_grid_urban_masonry",versionCode,geom,codeList, BuildGridFindAllVo.class));
        map.put("urban_other", fxqhBuildingGridRepository.findByVersionCodeAndGeom("fxqh_building_grid_urban_other",versionCode,geom,codeList, BuildGridFindAllVo.class));
        map.put("urban_steel", fxqhBuildingGridRepository.findByVersionCodeAndGeom("fxqh_building_grid_urban_steel",versionCode,geom, codeList,BuildGridFindAllVo.class));
        map.put("urban_steel_concrete", fxqhBuildingGridRepository.findByVersionCodeAndGeom("fxqh_building_grid_urban_steel_concrete",versionCode,geom, codeList,BuildGridFindAllVo.class));
        map.put("urban_wood", fxqhBuildingGridRepository.findByVersionCodeAndGeom("fxqh_building_grid_urban_wood",versionCode,geom, codeList,BuildGridFindAllVo.class));
        List<BuildGridFindAllVo> vos = new ArrayList<>();



        map.forEach((k, vList) -> {
            String hump = ObjUtils.hump(k.toString());

                for (BuildGridFindAllVo vo : vList) {
                    vo.setXpdId(UUIDGenerator.getUUID());
                    vo.setType(hump);
                    vo.setCreateTime(new Date());
                    vo.setCreateUser("123");
                    vo.setNewUpdate("1");

                    Map<String, Object> propertiesAsMap = getPropertiesAsMap(vo);
                    for (Map.Entry<String, Object> stringObjectEntry : propertiesAsMap.entrySet()) {
                        String key = stringObjectEntry.getKey();
                        Field[] declaredFields = vo.getClass().getDeclaredFields();
                        if (declaredFields.length > 0) {
                            try {
                                for (Field field : declaredFields) {
                                    field.setAccessible(true);
                                    String fieldName = field.getName();
                                    if (k.equals(fieldName)) {
                                        Object value = stringObjectEntry.getValue();
                                        if ("residence".equals(key) || "business".equals(key) || "office".equals(key) || "medic".equals(key) || "other".equals(key) || "totalArea".equals(key)) {
                                            //stringObjectEntry.get
                                            Double bval = ObjectUtils.isNotEmpty(value) ? Double.parseDouble(value.toString()) : 0;
                                            field.set(vo, bval);
                                        } else {
                                            field.set(vo, PlatformObjectUtils.isNotEmpty(value) ? value.toString() : "");
                                        }
                                    }
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    vos.add(vo);
                }

        });

        return vos;

    }

    //去除百分号（如果有）
    private String removePercent(String ratio) {

//        if(StringUtils.isBlank(ratio)){
//            return "50";
//        }
//        int index = -1;
//        if((index = ratio.lastIndexOf("%"))>-1){
//            ratio = ratio.substring(0,index);
//        }
        if(StringUtils.isBlank(ratio)){
           return "50.0";
        }
        // 将字符串转换为浮点数
        double originalValue = Double.parseDouble(ratio);

        // 扩大100倍
        double result = originalValue * 100;
        return Double.toString(result);
    }

    //解析上传的附件数据
    private List<HouseCategoryArea> analysisExcel(String attachId) throws Exception {
        //根据id获取磁盘上的excel文件
        AttachmentInfoEntity attach = attachmentInfoRepository.getAttach(attachId);
        File file = new File(attach.getFileDirId()+File.separator+attach.getAttachPath());
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new RuntimeException("获取总建筑面积失败,获取excel失败");
        }

//        File file = new File("D:\\static\\总建筑面积导入模板.xlsx");
        ImportParams params = new ImportParams();
        params.setHeadRows(2);
        params.setTitleRows(1);
        params.setNeedVerify(false);
        ExcelImportResult<HouseCategoryArea> result = ExcelImportUtil.importExcelMore(new FileInputStream(file), HouseCategoryArea.class, params);
        List<HouseCategoryArea> list = result.getList();
        if(PlatformObjectUtils.isEmpty(list)){
            throw  new RuntimeException("上传表中无数据，请重新上传");
        }
        //获取区县集合 对于合并单元格的数据进行单元格拆分数据
//        splitMergeCeilData(list);
//        return list;
        List<HouseCategoryArea> areaList = splitMergeCeilData(list);
        return areaList;
    }
    //获取区县集合 对于合并单元格的数据进行单元格拆分数据
//    private void splitMergeCeilData1(List<HouseCategoryArea> list){
//        //count是对逻辑进行优化，只需要对合并单元格的行取拆分，不需要每行的去拆分数据
//        AtomicInteger count = new AtomicInteger(0);
//        for(int i=0;i<list.size();i=i+count.get()){
//            count = new AtomicInteger(1);
//            String province = list.get(i).getProvince();
//            String city = list.get(i).getCity();
//            String county = list.get(i).getCounty();
//            for(int j=i+1;j<list.size();j++){
//                if(PlatformObjectUtils.isEmpty(list.get(j).getProvince()) && PlatformObjectUtils.isEmpty(list.get(j).getCity()) && PlatformObjectUtils.isEmpty(list.get(j).getCounty())){
//                    //表示是省市县合并了单元格
//                    list.get(j).setProvince(province);
//                    list.get(j).setCity(city);
//                    list.get(j).setCounty(county);
//                    count.getAndAdd(1);
//                }else{
//                    break;
//                }
//            }
//        }
//    }

    private List<HouseCategoryArea> splitMergeCeilData(List<HouseCategoryArea> areaList){
        HouseCategoryArea temp = new HouseCategoryArea();
        List<HouseCategoryArea> list = new ArrayList<>();
        for(int i=0;i<areaList.size();i++){
            HouseCategoryArea area = areaList.get(i);
            HouseCategoryArea houseCategoryArea = new HouseCategoryArea();
            houseCategoryArea.setProvince(area.getProvince());
            houseCategoryArea.setCity(area.getCity());
            houseCategoryArea.setCounty(area.getCounty());
            if(i==0){
                if(StringUtils.isBlank(area.getProvince()) && StringUtils.isBlank(area.getCity()) && StringUtils.isBlank(area.getCounty())){
                    throw new RuntimeException("第"+(i+1)+"行省市区县不能为空");
                }
            }else{
                if(StringUtils.isBlank(area.getProvince()) && StringUtils.isBlank(area.getCity()) && StringUtils.isBlank(area.getCounty())){
                    houseCategoryArea.setProvince(temp.getProvince());
                    houseCategoryArea.setCity(temp.getCity());
                    houseCategoryArea.setCounty(temp.getCounty());
                }else if(StringUtils.isBlank(area.getProvince()) && StringUtils.isBlank(area.getCity())){
                    houseCategoryArea.setProvince(temp.getProvince());
                    houseCategoryArea.setCity(temp.getCity());
                }else if(StringUtils.isBlank(area.getProvince())){
                    houseCategoryArea.setProvince(temp.getProvince());
                }
            }
            houseCategoryArea.setHousePurposeName(area.getHousePurposeName());
            houseCategoryArea.setV1Area(area.getV1Area()==null?BigDecimal.ZERO:area.getV1Area());
            houseCategoryArea.setV2Area(area.getV2Area()==null?BigDecimal.ZERO:area.getV2Area());
            houseCategoryArea.setV3Area(area.getV3Area()==null?BigDecimal.ZERO:area.getV3Area());
            houseCategoryArea.setV4Area(area.getV4Area()==null?BigDecimal.ZERO:area.getV4Area());
            houseCategoryArea.setV5Area(area.getV5Area()==null?BigDecimal.ZERO:area.getV5Area());
            houseCategoryArea.setV6Area(area.getV6Area()==null?BigDecimal.ZERO:area.getV6Area());
            houseCategoryArea.setV7Area(area.getV7Area()==null?BigDecimal.ZERO:area.getV7Area());
            houseCategoryArea.setV8Area(area.getV8Area()==null?BigDecimal.ZERO:area.getV8Area());
            houseCategoryArea.setV9Area(area.getV9Area()==null?BigDecimal.ZERO:area.getV9Area());
            houseCategoryArea.setV10Area(area.getV10Area()==null?BigDecimal.ZERO:area.getV10Area());
            temp = houseCategoryArea;
            list.add(houseCategoryArea);
        }
        return list;
    }

    private  List<HouseCategoryArea> getSurTaskData(List<HouseCategoryArea> list,String xsemCode,String finalRatio,String xsemId,String versionCode) throws Exception{
        Map<String, String> areaIdCodeMap = (Map<String, String>) JSONObject.parse(redisTemplate.opsForValue().get(FxfzConstants.CACHE_SYS_KEY + "areaIdCodeMap"));
        //获取该地震事件下的所有的评估子区
        List<SurTaskManage> allData = surTaskManageRepository.getAllDefineDataByCode(xsemId);
        if (PlatformObjectUtils.isEmpty(allData) || allData.size()==0) {
            throw new RuntimeException("该地震事件没有查询到任何的评估子区");
        }
        //按照省市区县房屋用途进行集合分组
        Map<String, List<HouseCategoryArea>> groupMap = list.stream().collect(Collectors.groupingBy(house -> {
            return house.getProvince() + "_" + house.getCity() + "_" + house.getCounty() + "_" + house.getHousePurposeName();
        }));
        //去重获取区县的信息
        List<String> countyList = list.stream().map(house->{
            return house.getProvince()+"_"+house.getCity()+"_"+house.getCounty();
        }).distinct().collect(Collectors.toList());
        List<HouseCategoryArea> areas = new ArrayList<>();
        //获取这些区县的空间信息
        for (String area : countyList) {
            String province = area.split("_")[0];
            String city = area.split("_")[1];
            String county = area.split("_")[2];
            try {
                //获取区县id
                String id = sysAreaService.getIdByCondition(URLEncoder.encode(province, "utf-8"), URLEncoder.encode(city, "utf-8"), URLEncoder.encode(county, "utf-8"));
                if(StringUtils.isNotBlank(id)){
                    if(id.split("_").length<3){
                        continue;
                        //throw new RuntimeException(province+""+city+""+county+"不存在");
                    }
                    String provinceId = id.split("_")[0];
                    String cityId = id.split("_")[1];
                    String countyId = id.split("_")[2];
                    //获取区县code，不能根据区县名称查询区县的空间数据，因为存在重名的区县名称
                    assert areaIdCodeMap != null;
                    String provinceCode = areaIdCodeMap.get(provinceId);
                    String cityCode = areaIdCodeMap.get(cityId);
                    String countyCode = areaIdCodeMap.get(countyId);
                    //根据区县code获取区县的空间数据
                    BoundaryEntity countyBoundary = boundaryRepository.getOneByCode(countyCode, "3");
                    if(countyBoundary!=null){
                        //区县的空间数据
                        String geom = countyBoundary.getGeom();
                        //获取该区县的普查数据
                        //List<BuildGridFindAllVo> voList = houseCategoryAreaRepository.getPcData(Collections.singletonList(countyCode));

                        List<BuildGridFindAllVo> voList = getBuildGridData(versionCode,"",Collections.singletonList(countyCode));
                        //获取区县的面积
                        BigDecimal totalArea = BigDecimal.ZERO;
                        if(PlatformObjectUtils.isNotEmpty(voList)){
                            totalArea =  voList.stream().filter(vo->PlatformObjectUtils.isNotEmpty(vo.getTotalArea())).map(vo->{
                                return BigDecimal.valueOf(vo.getTotalArea());
                            }).reduce(BigDecimal.ZERO,BigDecimal::add);
                        }
                        //遍历评估子区
                        for (SurTaskManage surTaskManage : allData) {
                            //区县和评估子区相交，取相交的空间区域
                            String stIntersection = houseCategoryAreaRepository.getSTIntersection(geom, surTaskManage.getGeom());
                            //获取相交空间区域中的所有的格网数据
                            if(StringUtils.isNotBlank(stIntersection)){
                                //List<BuildGridFindAllVo> factVos = houseCategoryAreaRepository.getPcData(stIntersection);

                                List<BuildGridFindAllVo> factVos = getBuildGridData(versionCode,geom,Collections.emptyList());

                                if(factVos.size()>0){
                                    //用户上传的数据是需要普查的数据来获取不同房屋用途下的不同结构的占比
                                    //处理数据获取不同房屋用途下各个结构类型的面积占比,factVos是区县在评估子区部分内的普查数据
                                    HashBasedTable<String, String, BigDecimal> ratio = getRatio(factVos, totalArea,finalRatio);
                                    //rowMap<城镇住宅,<结构类型,占比>>
                                    Map<String,Map<String,BigDecimal>> rowMap = ratio.rowMap();
                                    rowMap.forEach((k,v)->{
                                        List<HouseCategoryArea> houseCategoryAreas = groupMap.get(province + "_" + city + "_" + county + "_" + k);
                                        if(PlatformObjectUtils.isNotEmpty(houseCategoryAreas)){
                                            HouseCategoryArea houseCategoryArea = houseCategoryAreas.get(0);
                                            //每种房屋用途一条数据
                                            HouseCategoryArea finalArea = new HouseCategoryArea();
                                            finalArea.setXshcaId(UUIDGenerator.getUUID());
                                            finalArea.setXstmId(surTaskManage.getXstmId()).setXsemId(xsemId).setEvaluationSubareaName(surTaskManage.getEvaluationSubareaName())
                                                    .setProvince(province).setProvinceCode(provinceCode).setCity(city).setCityCode(cityCode).setCounty(county).setCountyCode(countyCode).setDelFlag("0")
                                                    .setHousePurposeName(k).setHousePurposeCode(getHousePurpose().inverse().get(k)).setCreateUserId(PlatformSessionUtils.getUserId()).setCreateTime(new Date());
                                            //获取比例面积
                                            getRatioArea(v,houseCategoryArea,finalArea);
                                            areas.add(finalArea);
                                        }
                                    });
                                }
                            }
                        }
                    }
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                throw new RuntimeException("获取数据失败");
            }
        }
        return areas;
    }
//    private  List<HouseCategoryArea> getSurTaskData(List<HouseCategoryArea> list,String xsemCode,String finalRatio) throws Exception{
//        Map<String, String> areaIdCodeMap = (Map<String, String>) JSONObject.parse(redisTemplate.opsForValue().get(FxfzConstants.CACHE_SYS_KEY + "areaIdCodeMap"));
//        //获取该地震事件下的所有的评估子区
//        List<SurTaskManage> allData = surTaskManageRepository.getAllDefineDataByCode(xsemCode);
//        if (PlatformObjectUtils.isEmpty(allData) || allData.size()==0) {
//            throw new RuntimeException("该地震事件没有查询到任何的评估子区");
//        }
//        //按照省市区县房屋用途进行集合分组
//        Map<String, List<HouseCategoryArea>> groupMap = list.stream().collect(Collectors.groupingBy(house -> {
//            return house.getProvince() + "_" + house.getCity() + "_" + house.getCounty() + "_" + house.getHousePurposeName();
//        }));
//        //去重获取区县的信息
//        List<String> countyList = list.stream().map(house->{
//            return house.getProvince()+"_"+house.getCity()+"_"+house.getCounty();
//        }).distinct().collect(Collectors.toList());
//        List<HouseCategoryArea> areas = new ArrayList<>();
//        //获取这些区县的空间信息
//        countyList.forEach(area->{
//            String province = area.split("_")[0];
//            String city = area.split("_")[1];
//            String county = area.split("_")[2];
//            try {
//                //获取区县id
//                String id = sysAreaService.getIdByCondition(URLEncoder.encode(province, "utf-8"), URLEncoder.encode(city, "utf-8"), URLEncoder.encode(county, "utf-8"));
//                if(StringUtils.isNotBlank(id)){
//                    if(id.split("_").length<3){
//                        throw new RuntimeException(province+""+city+""+county+"不存在");
//                    }
//                    String provinceId = id.split("_")[0];
//                    String cityId = id.split("_")[1];
//                    String countyId = id.split("_")[2];
//                    //获取区县code，不能根据区县名称查询区县的空间数据，因为存在重名的区县名称
//                    assert areaIdCodeMap != null;
//                    String provinceCode = areaIdCodeMap.get(provinceId);
//                    String cityCode = areaIdCodeMap.get(cityId);
//                    String countyCode = areaIdCodeMap.get(countyId);
//                    //根据区县code获取区县的空间数据
//                    BoundaryEntity countyBoundary = boundaryRepository.getOneByCode(countyCode, "3");
//                    if(countyBoundary!=null){
//                        //区县的空间数据
//                        String geom = countyBoundary.getGeom();
//                        //获取该区县的普查数据
//                        List<BuildGridFindAllVo> voList = houseCategoryAreaRepository.getPcData(Collections.singletonList(countyCode));
//                        //获取区县的面积
//                        BigDecimal totalArea = BigDecimal.ZERO;
//                        if(PlatformObjectUtils.isNotEmpty(voList)){
//                            totalArea =  voList.stream().filter(vo->PlatformObjectUtils.isNotEmpty(vo.getTotalArea())).map(vo->{
//                                return BigDecimal.valueOf(vo.getTotalArea());
//                            }).reduce(BigDecimal.ZERO,BigDecimal::add);
//                        }
//                        //遍历评估子区
//                        for (SurTaskManage surTaskManage : allData) {
//                            List<BuildGridFindAllVo> factVos = new ArrayList<>();
//                            //区县和评估子区相交，取相交的空间区域
//                            String stIntersection = houseCategoryAreaRepository.getSTIntersection(geom, surTaskManage.getGeom());
//                            //获取相交空间区域中的所有的格网数据
//                            if(StringUtils.isNotBlank(stIntersection)){
//                                if(PlatformObjectUtils.isNotEmpty(voList)){
//                                    for (BuildGridFindAllVo buildGridFindAllVo : voList) {
//                                        Boolean intersect = houseCategoryAreaRepository.getIntersectData(stIntersection,buildGridFindAllVo.getGeom());
//                                        if(intersect){
//                                            //相交表示该区县数据在子区中则统计
//                                            factVos.add(buildGridFindAllVo);
//                                        }
//                                    }
//                                }
//                                if(factVos.size()>0){
//                                    //用户上传的数据是需要普查的数据来获取不同房屋用途下的不同结构的占比
//                                    //处理数据获取不同房屋用途下各个结构类型的面积占比,factVos是区县在评估子区部分内的普查数据
//                                    HashBasedTable<String, String, BigDecimal> ratio = getRatio(factVos, totalArea,finalRatio);
//                                    //rowMap<城镇住宅,<结构类型,占比>>
//                                    Map<String,Map<String,BigDecimal>> rowMap = ratio.rowMap();
//                                    rowMap.forEach((k,v)->{
//                                        List<HouseCategoryArea> houseCategoryAreas = groupMap.get(province + "_" + city + "_" + county + "_" + k);
//                                        if(PlatformObjectUtils.isNotEmpty(houseCategoryAreas)){
//                                            HouseCategoryArea houseCategoryArea = houseCategoryAreas.get(0);
//                                            //每种房屋用途一条数据
//                                            HouseCategoryArea finalArea = new HouseCategoryArea();
//                                            finalArea.setXshcaId(UUIDGenerator.getUUID());
//                                            finalArea.setXstmId(surTaskManage.getXstmId()).setXsemCode(surTaskManage.getXsemCode()).setEvaluationSubareaName(surTaskManage.getEvaluationSubareaName())
//                                                    .setProvince(province).setProvinceCode(provinceCode).setCity(city).setCityCode(cityCode).setCounty(county).setCountyCode(countyCode).setDelFlag("0")
//                                                    .setHousePurposeName(k).setHousePurposeCode(getHousePurpose().inverse().get(k)).setCreateUserId(PlatformSessionUtils.getUserId()).setCreateTime(new Date());
//                                            //获取比例面积
//                                            getRatioArea(v,houseCategoryArea,finalArea);
//                                            areas.add(finalArea);
//                                        }
//                                    });
//                                }
//                            }
//                        }
//                    }
//                }
//            } catch (UnsupportedEncodingException e) {
//                e.printStackTrace();
//                throw new RuntimeException("获取数据失败");
//            }
//        });
//        return areas;
//    }

    //根据占比求面积
    private void getRatioArea(Map<String,BigDecimal> v,HouseCategoryArea houseCategoryArea ,HouseCategoryArea finalArea){
        v.forEach((k1,v1)->{
            Field[] declaredFields = houseCategoryArea.getClass().getDeclaredFields();
            if(declaredFields.length>0){
                try {
                    for(Field field : declaredFields){
                        field.setAccessible(true);
                        Transform transform = field.getAnnotation(Transform.class);
                        if(transform==null){
                            continue;
                        }
                        //fieldName为v1Area-v10Area
                        String fieldName = field.getName();
                        if(k1.equals(fieldName)){
                            //上传的excel中I类-vII类的面积
                            BigDecimal value = (BigDecimal) field.get(houseCategoryArea);
                            //v1是v类房屋用途下k1类结构类型占全县面积的比例
                            //result是county这个县在某个评估子区下v类房屋用途，k1类结构类型的面积值
                            BigDecimal result = value==null?BigDecimal.ZERO:value.multiply(v1);
                            for(Field field1 : finalArea.getClass().getDeclaredFields()){
                                field1.setAccessible(true);
                                String fieldName1 = field1.getName();
                                if(fieldName.equals(fieldName1)){
                                    field1.set(finalArea,result);
                                    break;
                                }
                            }
                        }
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        });
    }
    private HashBasedTable<String, String, BigDecimal> getRatio(List<BuildGridFindAllVo> factVos,BigDecimal totalArea,String finalRatio){
        //根据类型获取结构类型面积
        List<StructureVO> structureVos = getStructureListByStructureType(factVos, finalRatio);
        HashBasedTable<String, String, BigDecimal> table = HashBasedTable.create();
        if(PlatformObjectUtils.isNotEmpty(structureVos)){
            //按照房屋用途进行结构类型面积汇总
            Map<String, List<StructureVO>> collect = structureVos.stream().collect(Collectors.groupingBy(StructureVO::getHousePurposeName));
            collect.forEach((k,v)->{
                BigDecimal v1Area =v.stream().filter(structureVO->PlatformObjectUtils.isNotEmpty(structureVO.getV1Area())).map(StructureVO::getV1Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v1Ratio = v1Area.divide(totalArea, 2, RoundingMode.HALF_DOWN);
                table.put(k,"v1Area",v1Ratio);
                BigDecimal v2Area =v.stream().filter(structureVO->PlatformObjectUtils.isNotEmpty(structureVO.getV2Area())).map(StructureVO::getV2Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v2Ratio = v2Area.divide(totalArea, 2, RoundingMode.HALF_DOWN);
                table.put(k,"v2Area",v2Ratio);
                BigDecimal v3Area =v.stream().filter(structureVO->PlatformObjectUtils.isNotEmpty(structureVO.getV3Area())).map(StructureVO::getV3Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v3Ratio = v3Area.divide(totalArea, 2, RoundingMode.HALF_DOWN);
                table.put(k,"v3Area",v3Ratio);
                BigDecimal v4Area =v.stream().filter(structureVO->PlatformObjectUtils.isNotEmpty(structureVO.getV4Area())).map(StructureVO::getV4Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v4Ratio = v4Area.divide(totalArea, 2, RoundingMode.HALF_DOWN);
                table.put(k,"v4Area",v4Ratio);
                BigDecimal v5Area =v.stream().filter(structureVO->PlatformObjectUtils.isNotEmpty(structureVO.getV5Area())).map(StructureVO::getV5Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v5Ratio = v5Area.divide(totalArea, 2, RoundingMode.HALF_DOWN);
                table.put(k,"v5Area",v5Ratio);
                BigDecimal v6Area =v.stream().filter(structureVO->PlatformObjectUtils.isNotEmpty(structureVO.getV6Area())).map(StructureVO::getV6Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v6Ratio = v6Area.divide(totalArea, 2, RoundingMode.HALF_DOWN);
                table.put(k,"v6Area",v6Ratio);
                BigDecimal v7Area =v.stream().filter(structureVO->PlatformObjectUtils.isNotEmpty(structureVO.getV7Area())).map(StructureVO::getV7Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v7Ratio = v7Area.divide(totalArea, 2, RoundingMode.HALF_DOWN);
                table.put(k,"v7Area",v7Ratio);
                BigDecimal v8Area =v.stream().filter(structureVO->PlatformObjectUtils.isNotEmpty(structureVO.getV8Area())).map(StructureVO::getV8Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v8Ratio = v8Area.divide(totalArea, 2, RoundingMode.HALF_DOWN);
                table.put(k,"v8Area",v8Ratio);
                BigDecimal v9Area =v.stream().filter(structureVO->PlatformObjectUtils.isNotEmpty(structureVO.getV9Area())).map(StructureVO::getV9Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v9Ratio = v9Area.divide(totalArea, 2, RoundingMode.HALF_DOWN);
                table.put(k,"v9Area",v9Ratio);
                BigDecimal v10Area =v.stream().filter(structureVO->PlatformObjectUtils.isNotEmpty(structureVO.getV10Area())).map(StructureVO::getV10Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v10Ratio = v10Area.divide(totalArea, 2, RoundingMode.HALF_DOWN);
                table.put(k,"v10Area",v10Ratio);
            });
        }
        return table;
    }

    private List<HouseCategoryArea> handleData(List<BuildGridFindAllVo> factVos,SurTaskManage surTaskManage,String ratio,String xsemId) {
        //根据类型获取结构类型面积
        List<StructureVO> structureVos = getStructureListByStructureType(factVos, ratio);
        List<HouseCategoryArea> areaList = new ArrayList<>();
        if(PlatformObjectUtils.isNotEmpty(structureVos)){
            //按照房屋用途进行结构类型面积汇总
            Map<String, List<StructureVO>> collect = structureVos.stream().collect(Collectors.groupingBy(StructureVO::getHousePurposeName));
            //key是7类房屋用途中的一种，list是每类房屋用途中的各个结构类数据的面积
            collect.forEach((k,v)->{
                BigDecimal v1Area =v.stream().filter(structureVO -> PlatformObjectUtils.isNotEmpty(structureVO.getV1Area())).map(StructureVO::getV1Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v2Area =v.stream().filter(structureVO -> PlatformObjectUtils.isNotEmpty(structureVO.getV2Area())).map(StructureVO::getV2Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v3Area =v.stream().filter(structureVO -> PlatformObjectUtils.isNotEmpty(structureVO.getV3Area())).map(StructureVO::getV3Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v4Area =v.stream().filter(structureVO -> PlatformObjectUtils.isNotEmpty(structureVO.getV4Area())).map(StructureVO::getV4Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v5Area =v.stream().filter(structureVO -> PlatformObjectUtils.isNotEmpty(structureVO.getV5Area())).map(StructureVO::getV5Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v6Area =v.stream().filter(structureVO -> PlatformObjectUtils.isNotEmpty(structureVO.getV6Area())).map(StructureVO::getV6Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v7Area =v.stream().filter(structureVO -> PlatformObjectUtils.isNotEmpty(structureVO.getV7Area())).map(StructureVO::getV7Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v8Area =v.stream().filter(structureVO -> PlatformObjectUtils.isNotEmpty(structureVO.getV8Area())).map(StructureVO::getV8Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v9Area =v.stream().filter(structureVO -> PlatformObjectUtils.isNotEmpty(structureVO.getV9Area())).map(StructureVO::getV9Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                BigDecimal v10Area =v.stream().filter(structureVO -> PlatformObjectUtils.isNotEmpty(structureVO.getV10Area())).map(StructureVO::getV10Area).reduce(BigDecimal.ZERO,BigDecimal::add);
                HouseCategoryArea area = new HouseCategoryArea();
                HashBiMap<String, String> housePurposeMap = getHousePurpose();
                String houseTypeCode = housePurposeMap.inverse().get(v.get(0).getHousePurposeName());
                area.setEvaluationSubareaName(surTaskManage.getEvaluationSubareaName());
                area.setProvinceCode(v.get(0).getProvinceCode()).setProvince(v.get(0).getProvince()).setCity(v.get(0).getCity()).setCityCode(v.get(0).getCityCode())
                    .setCounty(v.get(0).getCounty()).setCountyCode(v.get(0).getCountyCode()).setHousePurposeCode(houseTypeCode).setHousePurposeName(v.get(0).getHousePurposeName())
                    .setV1Area(v1Area).setV2Area(v2Area).setV3Area(v3Area).setV4Area(v4Area).setV5Area(v5Area).setV6Area(v6Area).setV7Area(v7Area).setV8Area(v8Area)
                    .setV9Area(v9Area).setV10Area(v10Area).setXshcaId(UUIDGenerator.getUUID()).setXstmId(surTaskManage.getXstmId()).setXsemId(xsemId)
                    .setCreateTime(new Date()).setCreateUserId(PlatformSessionUtils.getUserId()).setDelFlag("0");
                areaList.add(area);
            });
        }
        return areaList;
    }

    //根据类型获取结构类型面积
    private  List<StructureVO> getStructureListByStructureType(List<BuildGridFindAllVo> factVos, String ratio) {
        List<StructureVO> structureVos = new ArrayList<>(factVos.size());
        for (BuildGridFindAllVo factVo : factVos) {
            //获取数据是13张表中哪一类数据
            String structureType = getStructureType(factVo.getType());
            if (structureType.contains("城镇")) {
                List<StructureVO> structureVOList = publicData(factVo, structureType, "城市", ratio);
                structureVos.addAll(structureVOList);
            }

            if (structureType.contains("农村")) {
                List<StructureVO> structureVOList = publicData(factVo, structureType, "农村", ratio);
                structureVos.addAll(structureVOList);
            }
        }
        return structureVos;
    }

    /**
     * 每条数据都有不同类型的房屋占比，根据13张表类型获取城市和农村，根据占比获取房屋用途，
     * ratio用于设置将医疗教育拆分成卫生系统和教育系统时，教育系统的占比。1-教育系统占比=卫生系统的占比
     * 取的普查数据中每条数据中不同房屋用途的面积
     */
    private List<StructureVO> publicData(BuildGridFindAllVo factVo,String structureType,String district,String ratio){
        //一条数据最多5中房屋用途，每种用途构造一条数据，最终实现一条数据拆分最多5条数据
        List<StructureVO> vos = new ArrayList<>(20);
        //district：城镇表示此数据是城市,农村的表示此数据是农村数据
        //住宅面积
        BigDecimal area = getArea(factVo.getResidence(),factVo.getTotalArea());
        if(area.compareTo(BigDecimal.ZERO)>0){
            StructureVO vo = new StructureVO();
            //表示住宅房屋有面积
            vo.setHousePurposeName(district+"住宅");
            selectByDistrict(district,vo,structureType,area);
            setPublicAttribute(factVo,vo);
            vos.add(vo);
        }
        //办公房屋
        area =  getArea(factVo.getOffice(),factVo.getTotalArea());
        if(area.compareTo(BigDecimal.ZERO)>0){
            //表示办公房屋有面积、
            StructureVO vo = new StructureVO();
            vo.setHousePurposeName("政府办公");
            selectByDistrict(district,vo,structureType,area);
            setPublicAttribute(factVo,vo);
            vos.add(vo);
        }
        //商业房屋
        area =  getArea(factVo.getBusiness(),factVo.getTotalArea());
        if(area.compareTo(BigDecimal.ZERO)>0){
            //表示商业房屋有面积、
            StructureVO vo = new StructureVO();
            vo.setHousePurposeName(district+"公用");
            selectByDistrict(district,vo,structureType,area);
            setPublicAttribute(factVo,vo);
            vos.add(vo);
        }
        //医疗教育
        area =  getArea(factVo.getMedic(),factVo.getTotalArea());
        if(area.compareTo(BigDecimal.ZERO)>0){
            //表示医疗教育有面积、
            //教育系统
            StructureVO eduStructure = new StructureVO();
            eduStructure.setHousePurposeName("教育系统");
            BigDecimal eduRatio = new BigDecimal(ratio).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_DOWN);
            //拆分后教育系统的面积
            BigDecimal eduArea = area.multiply(eduRatio);
            selectByDistrict(district,eduStructure,structureType,eduArea);
            setPublicAttribute(factVo,eduStructure);
            vos.add(eduStructure);
            //卫生系统
            StructureVO healthStructure = new StructureVO();
            healthStructure.setHousePurposeName("卫生系统");
            BigDecimal healthRatio = BigDecimal.ONE.subtract(eduRatio);
            //拆分后卫生系统的面积
            BigDecimal healthArea = area.multiply(healthRatio);
            selectByDistrict(district,healthStructure,structureType,healthArea);
            setPublicAttribute(factVo,healthStructure);
            vos.add(healthStructure);
        }
        //其他房屋
        area =  getArea(factVo.getOther(),factVo.getTotalArea());
        if(area.compareTo(BigDecimal.ZERO)>0){
            //表示其他房屋有面积、
            StructureVO vo = new StructureVO();
            vo.setHousePurposeName("其他房屋");
            selectByDistrict(district,vo,structureType,area);
            setPublicAttribute(factVo,vo);
            vos.add(vo);
        }
        return vos;
    }

    //设置公共属性
    private void setPublicAttribute(BuildGridFindAllVo factVo,StructureVO vo){
        vo.setProvince(factVo.getProvince());
        vo.setProvinceCode(factVo.getProvinceCode());
        vo.setCity(factVo.getCity());
        vo.setCityCode(factVo.getCityCode());
        vo.setCounty(factVo.getCounty());
        vo.setCountyCode(factVo.getCountyCode());
    }

    private void selectByDistrict(String district,StructureVO vo,String structureType,BigDecimal area){
        if("城市".equals(district)){
            publicCityData(structureType,vo,area);
        }else{
            publicNocityData(structureType,vo,area);
        }
    }
    //根据类型结构设置字段信息
    private void  publicCityData(String structureType,StructureVO vo,BigDecimal area){
        if("城镇砌体结构".equals(structureType)){
            vo.setV4Area(area);
        }
        if("城镇钢混结构".equals(structureType)){
            vo.setV2Area(area);
        }
        if("城镇钢结构".equals(structureType)){
            vo.setV1Area(area);
        }
        if("城镇木结构".equals(structureType)){
            vo.setV7Area(area);
        }
        if("城镇其他结构".equals(structureType)){
            vo.setV3Area(area);
        }
    }
    //根据类型结构设置字段信息
    private void publicNocityData(String structureType,StructureVO vo,BigDecimal area){
        if("农村砌体结构".equals(structureType)){
            vo.setV3Area(area);
        }
        if("农村土木（石木）结构".equals(structureType)){
            vo.setV6Area(area);
        }
        if("农村底部框架结构".equals(structureType)){
            vo.setV3Area(area);
        }
        if("农村木（竹）结构".equals(structureType)){
            vo.setV7Area(area);
        }
        if("农村混杂结构".equals(structureType)){
            vo.setV8Area(area);
        }
        if("农村钢混结构".equals(structureType)){
            vo.setV2Area(area);
        }
        if("农村钢结构".equals(structureType)){
            vo.setV1Area(area);
        }
        if("农村其他结构".equals(structureType)){
            vo.setV8Area(area);
        }
    }

    //获取房屋类型
    private List<String> getHouseTypeList(BuildGridFindAllVo factVo){
        List<String> houseTypeList = new ArrayList<>(7);
        if(panExist(factVo.getResidence(),factVo.getTotalArea())){
            //表示住宅房屋存在面积
            houseTypeList.add(getStructureType(factVo.getType()).contains("城镇")?"城市住宅":"农村住宅");
        }

        if(panExist(factVo.getOffice(),factVo.getTotalArea())){
            //表示政府办公存在面积
            houseTypeList.add("政府办公");
        }

        if(panExist(factVo.getBusiness(),factVo.getTotalArea())){
            //表示商业房屋存在面积
            houseTypeList.add(getStructureType(factVo.getType()).contains("城镇")?"城市公用":"农村公用");
        }

        if(panExist(factVo.getMedic(),factVo.getTotalArea())){
            //表示医疗教育存在面积
            houseTypeList.add("教育系统");
            houseTypeList.add("卫生系统");
        }

        if(panExist(factVo.getOther(),factVo.getTotalArea())){
            //表示住宅房屋存在面积
            houseTypeList.add("政府办公");
        }
        return houseTypeList;
    }

    private boolean panExist(Double ratio,Double totalArea){
        return compareVal(multiply(getBigDecimalVal(ratio),getBigDecimalVal(totalArea)),BigDecimal.ZERO)>0;
    }
    private BigDecimal getArea(Double ratio,Double totalArea){
        return multiply(getBigDecimalVal((BigDecimal.valueOf(ratio).divide(new BigDecimal(100),2,RoundingMode.HALF_DOWN)).doubleValue()),getBigDecimalVal(totalArea));
    }

    private BigDecimal getBigDecimalVal(Double val){
        return val==null?BigDecimal.ZERO:BigDecimal.valueOf(val);
    }
    private int compareVal(BigDecimal val1,BigDecimal val2){
        return val1.compareTo(val2);
    }

    private BigDecimal multiply(BigDecimal val1,BigDecimal val2){
        return val1.multiply(val2);
    }
    //获取普查类型
    private String getStructureType(String structureType){
        String structure = "";
        //城镇砌体结构
        if("urbanMasonry".equals(structureType)){
            structure = "城镇砌体结构";
        }
        //城镇钢混结构
        if("urbanSteelConcrete".equals(structureType)){
            structure = "城镇钢混结构";
        }
        //城镇钢结构
        if("urbanSteel".equals(structureType)){
            structure = "城镇钢结构";
        }
        //城镇木结构
        if("urbanWood".equals(structureType)){
            structure = "城镇木结构";
        }
        //城镇其他结构
        if("urbanOther".equals(structureType)){
            structure = "城镇其他结构";
        }
        //农村砌体结构
        if("ruralMasonry".equals(structureType)){
            structure = "农村砌体结构";
        }
        //农村底部框架结构
        if("ruralBottomFrame".equals(structureType)){
            structure = "农村底部框架结构";
        }
        //农村木（竹）结构
        if("ruralWoodBamboo".equals(structureType)){
            structure = "农村木（竹）结构";
        }
        //农村混杂结构
        if("ruralMixed".equals(structureType)){
            structure = "农村混杂结构";
        }
        //农村钢混结构
        if("ruralSteelConcrete".equals(structureType)){
            structure = "农村钢混结构";
        }
        //农村钢结构
        if("ruralSteel".equals(structureType)){
            structure = "农村钢结构";
        }
        //农村其他结构
        if("ruralOther".equals(structureType)){
            structure = "农村其他结构";
        }
        //农村土木（石木）结构
        if("ruralCivil".equals(structureType)){
            structure = structure = "农村土木（石木）结构";
        }
        return structure;
    }
    //获取房屋用途的字段项
    private HashBiMap<String, String> getHousePurpose(){
        List<DictItemEntity> dictItemList = dictItemRepository.findDictItemByDictId(Arrays.asList("2a540caa0860487db4fd21f278fc173e"));
        HashBiMap<String, String> housePurposeMap = HashBiMap.create();
        if(PlatformObjectUtils.isNotEmpty(dictItemList)){
            dictItemList.forEach(entity->{
                housePurposeMap.put(entity.getDictItemCode(),entity.getDictItemName());
            });
        }
        return housePurposeMap;
    }

    @Transactional(rollbackFor = Exception.class)
    public RestResponse delete(String  xshcaId) {
        int count = houseCategoryAreaRepository.deleteById(xshcaId);
        if(count>0){
            return ResponseCreator.createSuccessResponse("删除成功");
        }
        return ResponseCreator.createFailResponse("删除失败");
    }

    public RestResponse updatePage(String xshcaId) {
        return ResponseCreator.createSuccessResponse(houseCategoryAreaRepository.findById(xshcaId));
    }

    @Transactional(rollbackFor = Exception.class)
    public RestResponse toUpdate(HouseCategoryArea area) {
        int count  = houseCategoryAreaRepository.toUpdate(area);
        if(count>0){
            return ResponseCreator.createSuccessResponse("修改成功");
        }
        return ResponseCreator.createFailResponse("修改失败");
    }

    public RestResponse getProvinceList(String xsemCode) throws  Exception{
        EarEveManage currentEvent = earEveManageService.getCurrentEvent();
        List<SurTaskManage> allData = surTaskManageRepository.getAllDataByCode(currentEvent.getXsemId());
        if(PlatformObjectUtils.isEmpty(allData)){
            throw new RuntimeException("该地震事件没有关联任何评估子区");
        }
        List<BoundaryEntity> list = new ArrayList<>();
        if (PlatformObjectUtils.isNotEmpty(allData)) {
            allData.forEach(surTaskManage -> {
                List<BoundaryEntity> boundaryList = boundaryRepository.getProvinceBoundaryList(surTaskManage.getGeom());
                list.addAll(boundaryList);
            });
        }
        Map<String, String> collectMap = list.stream().distinct().collect(Collectors.toMap(BoundaryEntity::getName, BoundaryEntity::getCode));
        String jsonStr = sysAreaService.jsonSAreaTree("1");
        Gson gson = CreateGson.createGson();
        List sysMenuList = gson.fromJson(jsonStr, List.class);
        List<DistrictVO> vos = new ArrayList<>();
        if(PlatformObjectUtils.isNotEmpty(sysMenuList)){
            sysMenuList.forEach(entity->{
                LinkedTreeMap map = (LinkedTreeMap)entity;
                String name = map.get("name").toString();
                String id = map.get("id").toString();
                if(collectMap.containsKey(name)){
                    DistrictVO vo = new DistrictVO();
                    vo.setId(id);
                    vo.setName(name);
                    vos.add(vo);
                }
            });
        }
        return ResponseCreator.createSuccessResponse(vos);
    }

    public RestResponse getAreaList(String code, String level) {
        List<BoundaryEntity> areaList = boundaryRepository.getByCode(code,level);
        return ResponseCreator.createSuccessResponse(areaList);
    }

    public void getAndSavePcData() {
        //先删除
        houseCategoryAreaRepository.deletePcData("");
        String url = divisionUrl + "/buildingGrid/findAll";
        RestResponse data = remoteService.getJCSJ(url, 2, new JSONObject());
        JSONObject jsonObject =(JSONObject) data.getData();
        Map map=JSON.parseObject(jsonObject.toJSONString(),Map.class);
        List<BuildGridFindAllVo> vos = new ArrayList<>();
        map.forEach((k,v)->{
            String hump = ObjUtils.hump(k.toString());
            JSONArray jsonArray =(JSONArray) v;
            for (Object o : jsonArray) {
                JSONObject js = (JSONObject)  o;
                BuildGridFindAllVo vo = new BuildGridFindAllVo();
                vo.setXpdId(UUIDGenerator.getUUID());
                vo.setType(hump);
                vo.setCreateTime(new Date());
                vo.setCreateUser("123");
                vo.setNewUpdate("1");
                for (Map.Entry<String, Object> stringObjectEntry : js.entrySet()) {
                    String key = stringObjectEntry.getKey();
                    Field[] declaredFields = vo.getClass().getDeclaredFields();
                    if(declaredFields.length>0){
                        try {
                            for(Field field : declaredFields){
                                field.setAccessible(true);
                                String fieldName = field.getName();
                                if(key.equals(fieldName)){
                                     Object value = stringObjectEntry.getValue();
                                     if("residence".equals(key) || "business".equals(key)||"office".equals(key)||"medic".equals(key)||"other".equals(key)||"totalArea".equals(key)){
                                        //stringObjectEntry.get
                                         Double bval = ObjectUtils.isNotEmpty(value)?Double.parseDouble(value.toString()):0;
                                         field.set(vo,bval);
                                     }else{
                                         field.set(vo,PlatformObjectUtils.isNotEmpty(value)?value.toString():"");
                                     }
                                }
                            }
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
                vos.add(vo);
            }
        });
        //批量保存
        houseCategoryAreaRepository.batchSavePcData(vos);
    }

    public List<DictItemEntity> getHouseUseTo() {
        return dictItemRepository.findDictItemByDictId(Arrays.asList("2a540caa0860487db4fd21f278fc173e"));
    }
}
